package com.example.mykotilin.workmanager.lib.worker.filters

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.util.Log
import androidx.annotation.VisibleForTesting
import androidx.work.*
import com.example.mykotilin.workmanager.lib.Constants
import com.example.mykotilin.workmanager.lib.worker.createNotification
import java.io.*
import java.lang.IllegalArgumentException
import java.util.*
import com.example.mykotilin.R



abstract class BaseFilterWorker(context: Context, parameters: WorkerParameters) :
    CoroutineWorker(context, parameters) {

    override suspend fun doWork(): Result {
        val resourceUri = inputData.getString(Constants.KEY_IMAGE_URI)
            ?: throw IllegalArgumentException("Invalid input Uri")
        return try {
            //获取输入流
            val inputStream = inputStreamFor(applicationContext, resourceUri)
            //通过输入流解码成bitmap
            val bitmap = BitmapFactory.decodeStream(inputStream)
            //对bitmap进行相应处理
            val output = applyFilter(bitmap)
            //将bitmap写入到文件
            val outputUri = writeBitmapToFile(output)
            Result.success(workDataOf(Constants.KEY_IMAGE_URI to outputUri.toString()))
        } catch (fileNotFoundException: FileNotFoundException) {
            Log.e(TAG, "Failed to decode input stream", fileNotFoundException)
            Result.failure()
        } catch (throwable: Throwable) {
            Log.e(TAG, "Error applying filter", throwable)
            Result.failure()
        }
    }

    abstract fun applyFilter(input: Bitmap): Bitmap


    //将bitmap转换文件
    private fun writeBitmapToFile(bitmap: Bitmap): Uri {
        val name = "filter-output-${UUID.randomUUID()}.png"; //处理后图片名称
        val outputDir = File(applicationContext.filesDir, Constants.OUTPUT_PATH)//图片文件输出地址
        if (!outputDir.exists()) { //判断地址是否存在
            outputDir.mkdirs()
        }
        val outFile = File(outputDir, name) //构成文件
        var out: FileOutputStream? = null
        try {
            out = FileOutputStream(outFile) //写出文件流
            bitmap.compress(Bitmap.CompressFormat.PNG, 0, out)
        } finally {
            if (out != null) {
                try {
                    out.close()
                } catch (ignore: IOException) {

                }

            }
        }
        return Uri.fromFile(outFile)
    }



    override suspend fun getForegroundInfo(): ForegroundInfo {
        return ForegroundInfo(NOTIFICATION_ID, createNotification(applicationContext, id,
            applicationContext.getString(R.string.notification_title_filtering_image)))
    }

    companion object {
        const val TAG = "BaseFilterWorker"
        const val ASSET_PREFIX = "file:///android_asset/"

        // For a real world app you might want to use a different id for each Notification.
        const val NOTIFICATION_ID = 1


        @VisibleForTesting
        fun inputStreamFor(context: Context, resourceUri: String): InputStream? {
            return if (resourceUri.startsWith(ASSET_PREFIX)) {
                val assetManager = context.resources.assets
                assetManager.open(resourceUri.substring(ASSET_PREFIX.length))
            } else {
                val resolver = context.contentResolver
                resolver.openInputStream(Uri.parse(resourceUri))
            }
        }

    }

}